package com.nguyenho.foodbooking;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Configuration
@ImportResource("classpath*:**/configuration.xml")
@Service
public class FoodBooking {
	
	//web driver configuration
	@Autowired
	String webDriverType;
	@Autowired
	String webDriverPath;
	
	// web interfaces
	@Autowired
	String xpathTxtUserName;
	@Autowired
	String xpathTxtPassword;
	@Autowired
	String xpathBtnLogin;
	@Autowired
	String xpathBtnCanteen;
	@Autowired
	String xpathBtnOrder;
	@Autowired
	String xpathBtnBook;
	@Autowired
	String xpathBtnBookPara;
	@Autowired
	String xpathCurrentFood;

	//user data
	@Autowired
	String userName;
	@Autowired
	String password;
	@Autowired
	String crmPath;
	@Autowired
	String foodfilepath;
	
	WebDriver driver;
	long waitSecond = 10;
	
	@Scheduled(cron = "* ${data.ordertime.minute} ${data.ordertime.hour} ? * MON-FRI")
	public void executeTask() {
		
		DateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
		Date curDate = new Date();
		System.out.println("Current Date/Time now: " + dateFormat.format(curDate));
		
		try {
			//decrypt password
			String pass= PasswordUtil.decrypt(password);
			
			openBrowser(BrowserType.getValueOf(webDriverType),crmPath);
			login(userName, pass);
			gotoBookingPage();
			
			String bookFood = null;
			String curFood = getText(xpathCurrentFood);
			
			System.out.println("curFood = " + curFood);
			//check current food in the order menu
			String[] menu = readMenu(foodfilepath);
			for( int i = 0; i <= menu.length - 1; i++){
				if (curFood.equals(menu[i])) {
					bookFood = curFood;
					break;
				}
			}
			
			System.out.println("bookFood = " + bookFood);
			
			// book if food is in the order menu
			if (bookFood!=null){
				String btnOrderFood = String.format(xpathBtnBookPara, bookFood);
				click(btnOrderFood);
			}
			
			closeBrowser();
			
		} catch (IOException | GeneralSecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void login(String userName, String password){
		waitForElementPresent(xpathTxtUserName, true, waitSecond);
		type(xpathTxtUserName, userName);
		type(xpathTxtPassword, password);
		click(xpathBtnLogin);
	}
	
	public void gotoBookingPage(){
		waitForElementPresent(xpathBtnCanteen, true, waitSecond);
		click(xpathBtnCanteen);
		waitForElementPresent(xpathBtnOrder, true, waitSecond);
		click(xpathBtnOrder);
		waitForElementPresent(xpathBtnBook, true, waitSecond);
	}
	
	public String[] readMenu(String filename) throws IOException {
        FileReader fileReader = new FileReader(filename);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        List<String> lines = new ArrayList<String>();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            lines.add(line);
        }
        bufferedReader.close();
        return lines.toArray(new String[lines.size()]);
    }
	
	public void openBrowser(BrowserType browserType, String url) {
	    driver = getWebDriver(browserType);
	    driver.get(url);
	}

	public void closeBrowser() {
	    driver.close();
	}

	public boolean isElementExists(String locator) {
		if (driver.findElements(By.xpath(locator)).size() > 0){
			return true;
		}
		else{
			System.out.println("no element found: " + locator.toString());
			return false;
		}
	}
	
	public void click(String locator) {
		if (isElementExists(locator))
			driver.findElement(By.xpath(locator)).click();
	}
	
	public String getText(String locator) {
		return (isElementExists(locator)) ? driver.findElement(By.xpath(locator)).getText() : null;
	}
	
	public void type(String locator, String text) {
		if (isElementExists(locator)){
			driver.findElement(By.xpath(locator)).clear();
			driver.findElement(By.xpath(locator)).sendKeys(text);
		}
	}
	
	public void waitForElementPresent(String locator, boolean expected, long second) {
		WebDriverWait wait = new WebDriverWait(driver, second);
		if (expected)
			wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(locator)));
		else
			wait.until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(By.xpath(locator))));
	}
	
	public String getAttribute(String locator, String attribute) {		
		return (isElementExists(locator)) ? driver.findElement(By.xpath(locator)).getAttribute(attribute) : null;
	}
	
	public WebDriver getWebDriver(BrowserType browserType) {
	    switch (browserType) {
	        case FIREFOX:
	        	ProfilesIni allProfiles = new ProfilesIni();
	        	FirefoxProfile profile = allProfiles.getProfile("default");
	        	return new FirefoxDriver(profile);
	        case IE:
				DesiredCapabilities capability=DesiredCapabilities.internetExplorer();
				capability.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
				System.setProperty("webdriver.ie.driver", webDriverPath);
				return new InternetExplorerDriver(capability);
	        case CHROME:
	        	System.setProperty("webdriver.chrome.driver", webDriverPath);
	        	return new ChromeDriver();
	        default:
	            throw new RuntimeException("Browser type unsupported");
	    }
	}

	public enum BrowserType {
	    FIREFOX, IE, CHROME;
	     
	    public static BrowserType getValueOf(String value){
	    	if (value.equals("ie")) 
	    		return IE;
	    	else if (value.equals("chrome"))
	    		return CHROME;
	    	else
	    		return FIREFOX;
	    }
	}
	
	
}
